package day11.HomeWork;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

//a.银行账户余额查询与转账,
// 使用ReentrantReadWriteLock实现银行账户系统，
// 支持并发余额查询但互斥转账操作
// (提示: 提供三个方法 查询(读锁)  存款(写锁)  取款(写锁))
public class BankSystem {
    double balance = 0;
    ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock(true);

    public void show() {    //查询余额
        try {
            rrwl.readLock().lock();
            System.out.println("剩余余额:" + balance);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rrwl.readLock().unlock();
        }
    }

    public void deposit(int amount) {    //存款
        try {
            String name = Thread.currentThread().getName();
            rrwl.writeLock().lock();
            balance += amount;
            System.out.println(name + "存储了" + amount + "元");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rrwl.writeLock().unlock();
        }
    }

    public void withdrow(int amount) {    //取款
        try {
            String name = Thread.currentThread().getName();
            rrwl.writeLock().lock();
            if (amount <= balance) {
                balance -= amount;
                System.out.println(name + "取出了" + amount + "元");
                Thread.sleep(1000);
            } else {
                System.out.println(name + "想取出" + amount + "元, 但是余额不足");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rrwl.writeLock().unlock();
        }
    }

    public static void main(String[] args) {
        Random r = new Random();
        BankSystem bs = new BankSystem();
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                bs.deposit(r.nextInt(100) + 1);
            }
        }, "线程1:").start();
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                bs.withdrow(r.nextInt(100) + 1);
            }
        }, "线程2:").start();
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                bs.show();
            }
        }).start();
    }
}
